package org.jeecg.modules.pay.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.codec.binary.Base64;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonThirdConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.MD5Util;
import org.jeecg.config.mybatis.TenantContext;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.config.thirdapp.ThirdAppTypeItemVo;
import org.jeecg.modules.arc.service.IArcAccountService;
import org.jeecg.modules.arc.vo.ArcAccountCusVO;
import org.jeecg.modules.chg.entity.ChgArrears;
import org.jeecg.modules.chg.entity.ChgPayments;
import org.jeecg.modules.chg.service.IChgArrearsService;
import org.jeecg.modules.chg.service.IChgFeesService;
import org.jeecg.modules.chg.vo.ChgChargeFeeVo;
import org.jeecg.modules.pay.beans.beanAbc.*;
import org.jeecg.modules.pay.service.IBillReceiveService;
import org.jeecg.modules.pay.utils.Base64Util;
import org.jeecg.modules.pay.utils.HttpClientUtils;
import org.jeecg.modules.pay.utils.SignAndVerificationForAbc;
import org.jeecg.modules.rest.handle.CommonAbcRestHandle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

@Service("billReceiveAbcService")
public class BillReceiveAbcServiceImpl extends CommonAbcRestHandle implements IBillReceiveService {
   @Autowired
   ThirdAppConfig thirdAppConfig;
   @Autowired
   private SignAndVerificationForAbc signAndVerificationForAbc;
   @Autowired
   private IChgArrearsService chgArrearsService;
   @Autowired
   private IChgFeesService chgFeesService;
   @Autowired
   private IArcAccountService accountService;

   @Override
   public JSONObject queryBill(Map<String, String> requestMap,QueryBillRequest.Message.Info info
           ,QueryBillResponse.Message.Info respInfo) throws UnsupportedEncodingException {

       JSONObject resObj=new JSONObject();
       String responseJson = null;

       //解析前的requsetBody
       String requsetBody=requestMap.get("requsetBody");
       //获取缴费中心传送过来的签名
       String signatureString=requestMap.get("signatureString");
       // 验签
       ThirdAppTypeItemVo payAbcItem = thirdAppConfig.getPayAbc();
       boolean isSign= signAndVerificationForAbc.read_cer_and_verify_sign(payAbcItem,requsetBody, signatureString);

       if(!isSign){
           resObj.put("code","JH02");
           resObj.put("msg","验签失败");
           return resObj;
       }
       ArrayList<QueryBillResponse.Message.Info.Bill> respBills = new ArrayList<QueryBillResponse.Message.Info.Bill>();
       ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail> respDescDetail = new ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail>();

       String accName="";
       String readMonth="";
       int monthNum=0;
       String arrearsIds="";
       BigDecimal sumMoney=new BigDecimal(0.0);
       //根据缴费账号获取欠费账单记录
       /***
        * 场景 3【金额规则为 0，欠费账单支付，客户实际欠费多个子账单，但查询返回报文通过后台处理，将多个子账
        * 单经过计算得出汇总欠费金额，并通过单个子账单的形式返回，同时将客户每期子账单的明细信息放在 sCpt、sVal
        * 键值对里进行详情展示】
        *
        */
       JSONArray feeArray = new JSONArray();
       TenantContext.setTenant("16");

       //缴费账户对应 用户水表信息
       List<ArcAccountCusVO> cusVOList = accountService.queryAccount(null, null,info.getInput1());
       if(null == cusVOList || cusVOList.size()== 0 || cusVOList.toString().toLowerCase().equals("[null]")){
           resObj.put("code","JH02");
           resObj.put("msg","缴费信息不存在");
           return resObj;
       }

       List<ChgArrears> arrearsList = chgArrearsService.getArrearBillList(info.getInput1());
       if(null != arrearsList && arrearsList.size()>0){
           for (ChgArrears arrears : arrearsList) {
               monthNum++;
               accName=arrears.getCusName();
               if(readMonth.length()>1){
                   readMonth=readMonth+"、"+arrears.getReadMonth();
                   arrearsIds=arrearsIds+","+arrears.getId();
               }else{
                   readMonth=arrears.getReadMonth();
                   arrearsIds=arrears.getId();
               }

               BigDecimal itemMoney=arrears.getArrearMoney().subtract(arrears.getRecivedMoney())
                       .setScale(2, BigDecimal.ROUND_HALF_UP);
               sumMoney=sumMoney.add(itemMoney);

               String scpt="【"+arrears.getReadMonth()+"缴费单】";
               String sval=arrears.getReadMonth()+"月份欠费账单：水费："+arrears.getTotalMoney().toString()
                       +"||污水费："+arrears.getWuMoney().toString()
                       +"||垃圾费："+arrears.getLjMoney().toString()
                       +"||违约金："+arrears.getPenalty().toString()
                       +"||欠费金额："+itemMoney.toString()
                       ;

               JSONObject itemObject = new JSONObject();
               itemObject.put("scpt",scpt);
               itemObject.put("sval",sval);
               feeArray.add(itemObject);
           }
       }else{
           //没有欠费-允许预缴充值


           //resObj.put("code","JH07");
           //resObj.put("msg","无欠费记录或已缴清");
           //return resObj;
       }
       if(feeArray.size()>0 || 1==1){
           ArcAccountCusVO cusVO = cusVOList.get(0);

           ChgChargeFeeVo chargeFeeVo = new ChgChargeFeeVo();
           chargeFeeVo.setAccCode(info.getInput1());
           System.out.println(chargeFeeVo.getAccCode()+"-------------正在生成农行预订单------------");
           chargeFeeVo.setId(cusVO.getId());
           chargeFeeVo.setAccName("".equals(accName) ? cusVO.getAccName() :  accName);
           chargeFeeVo.setFeePayWay("5");//支付方式 3微信 4系统扣费 5农行
           chargeFeeVo.setFeeTollWay("3");//收费方式 3余额预存（收费剩下）
           chargeFeeVo.setFeeWholeWay("01");//整收方式 实收 02不扣余额
           //paymentsPage.setBillTypeId(null);//票据类型
           //paymentsPage.setFeePrintWay(null);//打印方式

           QueryBillResponse.Message.Info.Bill respBill = respInfo.new Bill();

           //应缴： 余额-应缴账单, 大于0时， 余额足够，应缴0，余额=余额-应缴账单  否则：余额=0 应缴= 余额-应缴账单，
           BigDecimal payMoney= cusVO.getAccBalance().subtract(sumMoney);
           //BigDecimal payMoney= sumMoney;//农行会自动帮扣余额，计算应付金额
           if(payMoney.doubleValue()>0){
               //余额充足
               chargeFeeVo.setPayFee(new BigDecimal(0));//实付|付款
               chargeFeeVo.setRealFee(new BigDecimal(0));//实缴：应收-余额
               respBill.setBalance(payMoney.toString());//余额
           }else{
               //余额不足
               chargeFeeVo.setPayFee(new BigDecimal(0));//实付|付款
               chargeFeeVo.setRealFee(payMoney.abs());//实缴：应收-余额
               respBill.setBalance("0.0");//余额
           }
           chargeFeeVo.setReceFee(sumMoney);//应缴|应收
           chargeFeeVo.setZeroFee(new BigDecimal(0).setScale(0,BigDecimal.ROUND_HALF_UP));//找零

           JSONObject orderObj=new JSONObject();
           orderObj.put("arrearIds",arrearsIds);

           int tid= Integer.parseInt(TenantContext.getTenant());
           String s = "abcSf"+ String.format("%0" + 4 + "d", tid);
           orderObj.put("createBy",s);
           //生成预支付订单
           ChgPayments chgPayments = chgFeesService.storedPreCharge(chargeFeeVo,orderObj);

           respBill.setBillNo("JP"+chgPayments.getId());

           if(monthNum<2){
               respBill.setBillName(info.getInput1()+"-"+readMonth+"月份的账单");
           }else {
               respBill.setBillName(info.getInput1()+" "+readMonth+"-"+monthNum+"个月份的账单");
           }
           //欠费金额
           //if(chgPayments.getAccCode().equals("8022030")){
           //     respBill.setOweAmt("0.01");
           //}else{
                respBill.setOweAmt(payMoney.abs().toString());
           //}
           respBill.setFeeAmt("0.00");//手续费
//           respBill.setExpireDate("20220930");

           for (Object obj : feeArray) {
               JSONObject itemObj=(JSONObject)obj;
               QueryBillResponse.Message.Info.Bill.DescDetail descDetail = respBill.new DescDetail(itemObj.getString("scpt"),itemObj.getString("sval"));
               respDescDetail.add(descDetail);
           }
           QueryBillResponse.Message.Info.Bill.DescDetail descDetail = respBill.new DescDetail("上次余额",cusVO.getAccBalance().toString()+"元");
           respDescDetail.add(descDetail);

           respBill.setDescDetails(respDescDetail);
           respBills.add(respBill);

           respInfo.setBill(respBills);
           respInfo.setRemark("农行查账单");

           //金额规则字段
           String amtRule = "3"; // 存在子账单时只能使用0  单个账单可以使用 3可以充值
           respInfo.setAmtRule(amtRule);
           respInfo.setTotalBillCount("1");//合并账单1
           respInfo.setCustName("".equals(accName) ? cusVO.getAccName() :  accName);
           respInfo.setCustAddress(cusVO.getAccAddress());

           //缓存信息
           StringBuffer cacheSb=new StringBuffer();
           cacheSb.append(TenantContext.getTenant()+";");
           cacheSb.append(chgPayments.getId()+";");//
           cacheSb.append(s+";");
           cacheSb.append(arrearsIds+";");
           cacheSb.append(sumMoney.floatValue()+";");//receFee -- 应缴金额（欠费金额）


           orderObj.put("tenantId",TenantContext.getTenant());
           orderObj.put("cashier",s);

           respInfo.setCacheMem(cacheSb.toString());
           //缴费项目编号--agentId:JF-EPAY2022083118182
           respInfo.setEpayCode(payAbcItem.getAgentId());
           //主商户编号--client-id:103881350003391
           respInfo.setMerchantId(info.getMerchantId());
           //缴费中心流水号
           respInfo.setTraceNo(info.getTraceNo());

           //respInfo.setRemark("备注信息为空");
//           respInfo.setCallBackText("MWS微水务平台");
//           String cbuTxt="http://mwsgzh.usw.cn/#/pages/home/home?jwid=gh_78b3defc9ec3&appid=wx50d1563f095ee8ba";
//			//respInfo.setCallBackUrl("http://mwsgzh.usw.cn/#/pages/home/home?jwid=gh_78b3defc9ec3&appid=wx50d1563f095ee8ba");
//		    //使用base64加密信息
//           respInfo.setCallBackUrl(Base64Util.encodeData(cbuTxt));
           resObj.put("code","0000");
           resObj.put("msg","查询欠费账单成功");
           resObj.put("bill",respInfo);
           return resObj;
       }
       return resObj;
   }

    @Override
    public JSONObject saleBill(ChargeBillRequest.Message.Head head
            ,ChargeBillRequest.Message.Info info) throws UnsupportedEncodingException {

        String traceNo = info.getTraceNo();//
        String amtRule = info.getAmtRule();//0：固定金额缴费 3：预充值缴费
        String payBillCount = info.getPayBillCount();// 合并支付的子账单数
        String payBillAmt = info.getPayBillAmt();//合并支付的子账单累加总金额
        String payBillNo = info.getPayBillNo();// 合并支付的子账单
        String transDate = info.getTransDate();//transDate 支付系统交易日期
        String transTime = info.getTransTime();//transTime 支付系统交易时间
        String cacheMem = info.getCacheMem();//缓存 0016;abcSf0016;arrearIds

        //缓存信息
        String[] cacheSpilt = cacheMem.split(";");

        JSONObject cacheMemObj= new JSONObject();

        cacheMemObj.put("amtRule",amtRule);
        cacheMemObj.put("tenantId",cacheSpilt[0]);
        cacheMemObj.put("paymentId",cacheSpilt[1]);
        cacheMemObj.put("cashier",cacheSpilt[2]);
        cacheMemObj.put("arrearIds", cacheSpilt.length>3 ? cacheSpilt[3] : "");
        cacheMemObj.put("receFee", cacheSpilt.length>4 ? cacheSpilt[4] : ""); //-- 应缴金额（欠费金额）
        cacheMemObj.put("payBillAmt",payBillAmt);
        cacheMemObj.put("payBillNo",payBillNo);
        cacheMemObj.put("transDate",transDate);
        cacheMemObj.put("transTime",transTime);
        cacheMemObj.put("transSeqNum",head.getTransSeqNum());
        cacheMemObj.put("traceNo",traceNo);
        System.out.println(cacheMemObj.toJSONString());

        JSONObject resObj = chgFeesService.abcHeXiaoCharge(cacheMemObj);

        return resObj;
    }

    //账单查询
    @Override
    public JSONObject abcBillQuery(ChgPayments chgPayments) {
        JSONObject resObj= new JSONObject();
        //输入项避免首尾出现空格的情况
        ThirdAppTypeItemVo payAbcItem = thirdAppConfig.getPayAbc();
        String merchantId = payAbcItem.getClientId();

        //创建发送请求对象
        ConfirmTraceRequest req = new ConfirmTraceRequest();
        //以系统当前时间为时间戳
        String timeStamp =DateUtils.formatDate("yyyyMMddHHmmssSSS");

        //封装数据格式为json格式 固定
        req.setFormat("json");
        // 关联交易的交易序列号需由第三方提供，且必须按照特定规则上送缴费中心，规则定义：BRIDGE前缀+当前17位时间戳timeStamp+商户号merchantId
        req.getMessage().getHead().setTransSeqNum("BRIDGE"+timeStamp+merchantId);
        //交易码，固定
        req.getMessage().getHead().setTransCode("confirmTrace");
        //上下行标志 固定
        req.getMessage().getHead().setTransFlag("01");
        //时间戳格式 yyyyMMddHHmmssSSS，
        req.getMessage().getHead().setTimestamp(timeStamp);

        //缴费中心商户编号，以商户为唯一维度来下载对账单
        req.getMessage().getInfo().setMerchantId(merchantId);
        //交易码
        req.getMessage().getInfo().setTraceNo(chgPayments.getTransactionId());

        //将封装的请求对象转化为json格式
        String reqJson = JSON.toJSONString(req);
        //logger.info("加密前发送的请求报文：" + reqJson);
        //加签名
        String signatrue = signAndVerificationForAbc.signWhithsha1withrsa(thirdAppConfig.getPayAbc(),reqJson);
        //拼接发送的报文信息
        String reqStr = signatrue+"||"+Base64Util.encodeData(reqJson);
        //logger.info("发送的请求报文：" + reqStr);
        String responseStr = HttpClientUtils.doPostStr(CommonThirdConstant.ABC_BRIDGE_CONFIRMTRACE, reqStr);
        //TODO 如下可以对返回的报文进行处理，封装到map回显到页面，也可以做其他处理
        if (responseStr.startsWith("{\"string\":")){
            //如果系统发生异常则会返回"{"string":"异常信息"}"
            //map.put("returnMessage", responseStr.substring(responseStr.indexOf(":") + 2,responseStr.indexOf("}")-1));
            resObj.put("code","300");
            resObj.put("msg",responseStr.substring(responseStr.indexOf(":") + 2,responseStr.indexOf("}")-1));
            return resObj;
        }else{
            //截取签名信息
            String headSub = responseStr.substring(0, responseStr.indexOf("||"));
            //log.info("获取签名的前半部分："+headSub);
            //截取加密的json信息，进行解密
            String tailSub = responseStr.substring(responseStr.indexOf("||")+2);
            //logger.info("获取签名的后半部分："+tailSub);
            //对获取的信息进行验签(该方法对signWhithsha1withrsa加密和Base64Util解密的字符串可以直接进行验签)
            Boolean isSign = signAndVerificationForAbc.read_cer_and_verify_sign(thirdAppConfig.getPayAbc(), tailSub, headSub);
            if(isSign){
                //解密返回报文
                String respJson = Base64Util.decodeData(tailSub);
                System.out.println("获取签名解密后："+respJson);
                //截取签名信息中的json字符串，并转化为对象
                ConfirmTraceResponse confirmTraceResponse = JSON.parseObject(respJson,
                        new TypeReference<ConfirmTraceResponse>(){});

                ConfirmTraceResponse.Message.Head resHead = confirmTraceResponse.getMessage().getHead();
                ConfirmTraceResponse.Message.Info resInfo = confirmTraceResponse.getMessage().getInfo();

                String returnCode = resHead.getReturnCode();
                String resTimeStamp = resHead.getTimeStamp();//缴费中心交易序列号
                String returnMessage = resHead.getReturnMessage();
                if( !"0000".equals(returnCode)){
                    resObj.put("code","300");
                    resObj.put("msg",returnMessage);
                    return resObj;
                }else{
                    String payStatus = resInfo.getPayStatus();
                    String payStatusMessage = resInfo.getPayStatusMessage();
                    resObj.put("code","200");
                    resObj.put("msg",payStatus+":"+payStatusMessage);
                    return resObj;
                }
            }else{
                resObj.put("code","300");
                resObj.put("msg","返回签名解析失败");
                return resObj;
            }
        }
    }


    /**取消缴费-取消收费*/
    @Override
    public JSONObject cancelAbcPay(ChgPayments chgPayments) throws UnsupportedEncodingException {
        ThirdAppTypeItemVo payAbcItem = thirdAppConfig.getPayAbc();
        JSONObject resObj= new JSONObject();

        //JSONObject cancelPayObj= new JSONObject();
        //cancelPayObj.put("paymentId",chgPayments.getId());
        //cancelPayObj.put("timeStamp",DateUtils.getDate("YYYYMMDDHHMMSSSSS"));//时间戳
        //cancelPayObj.put("transFlag","01");//交易上行下送标志
        //cancelPayObj.put("transCode","refundTrace");//交易码
        //cancelPayObj.put("branchCode","2350");//分行 4 位 iGoal 码
        //cancelPayObj.put("transSeqNum",chgPayments.getSerialNo());//缴费中心交易序列号
        //
        //cancelPayObj.put("traceNo",chgPayments.getTransactionId());//缴费中心流水号
        //cancelPayObj.put("merchantId",payAbcItem.getClientId());//商户编号
        //cancelPayObj.put("amtRefund",chgPayments.getPayFee());//退款金额

        RefundTraceRequest refundTraceRequest = new RefundTraceRequest();
        RefundTraceRequest.Message.Head head = refundTraceRequest.getMessage().getHead();
        RefundTraceRequest.Message.Info info = refundTraceRequest.getMessage().getInfo();

        //以系统当前时间为时间戳
        String timeStampt =DateUtils.formatDate("yyyyMMddHHmmssSSS");

        //head.setTransSeqNum(chgPayments.getSerialNo());
        head.setTransCode("refundTrace");
        head.setTransFlag("01");
        head.setTimeStamp(timeStampt);
        head.setBranchCode("2350");//福建分行
        // 关联交易的交易序列号需由第三方提供，且必须按照特定规则上送缴费中心，规则定义：BRIDGE前缀+当前17位时间戳timeStamp+缴费中心流水号
        head.setTransSeqNum("BRIDGE"+timeStampt+chgPayments.getTransactionId());

        info.setMerchantId(payAbcItem.getClientId());
        info.setTraceNo(chgPayments.getTransactionId());

        info.setAmtRefund(chgPayments.getPayFee().toString());
        //if(chgPayments.getAccCode().equals("8022030")){
        //    info.setAmtRefund("0.01");
        //}else {
            info.setAmtRefund(chgPayments.getPayFee().toString());
        //}

        refundTraceRequest.getMessage().setHead(head);
        refundTraceRequest.getMessage().setInfo(info);
        refundTraceRequest.setFormat("json");

        String requestJson = JSON.toJSONString(refundTraceRequest);
        System.out.println("退款申请报文:"+requestJson);
        //加签名
        String signatrue = signAndVerificationForAbc.signWhithsha1withrsa(thirdAppConfig.getPayAbc(),requestJson);
        //log.info("-----ChargeBillController------------responseJson打印结果是（responseJson加密前）:" + responseJson);
        requestJson = signatrue + "||"
                + new String(Base64.encodeBase64(requestJson.getBytes("utf-8")));
//                log.info("-----ChargeBillController------------responseJson打印结果是（responseJson加密后）:" + responseJson);
//        httpResponse.setCharacterEncoding("utf-8");
//        httpResponse.setContentType("text/plain");
//        httpResponse.getWriter().write(requestJson);

//        logger.info("发送的请求报文："+reqStr);
        //发送签名信息获取返回签名信息
        String responseStr = HttpClientUtils.doPostStr(CommonThirdConstant.ABC_BRIDGE_REFUNDTRACE, requestJson);
//        log.info("发送请求的地址："+reqUrl);
//        log.info("返回的响应报文："+responseStr);

        //TODO 如下可以对返回的报文进行处理，
        if (responseStr.startsWith("{\"string\":")){
            //如果系统发生异常则会返回"{"string":"异常信息"}"
            resObj.put("code","300");
            resObj.put("msg",responseStr.substring(responseStr.indexOf(":")+2,responseStr.indexOf("}")-1));
        }else{
            //截取签名信息
            String headSub = responseStr.substring(0, responseStr.indexOf("||"));
            //logger.info("获取签名的前半部分："+headSub);
            //截取加密的json信息，进行解密
            String tailSub = responseStr.substring(responseStr.indexOf("||")+2);
           // logger.info("获取签名的后半部分："+tailSub);

            //对获取的信息进行验签(该方法对signWhithsha1withrsa加密和Base64Util解密的字符串可以直接进行验签)
            try {
                Boolean isSign = signAndVerificationForAbc.read_cer_and_verify_sign(thirdAppConfig.getPayAbc(), tailSub, headSub);
                if(isSign){
                    //解密返回报文
                    String respJson = Base64Util.decodeData(tailSub);
                    System.out.println("退款申请返回解密报文:"+respJson);

                    //截取签名信息中的json字符串，并转化为对象
                    RefundTraceResponse refundTraceResponse = JSON.parseObject(respJson, new TypeReference<RefundTraceResponse>(){});
                    RefundTraceResponse.Message.Head resHead = refundTraceResponse.getMessage().getHead();
                    RefundTraceResponse.Message.Info resInfo = refundTraceResponse.getMessage().getInfo();

                    String returnCode = resHead.getReturnCode();
                    String timeStamp = resHead.getTimeStamp();//缴费中心交易序列号
                    String returnMessage = resHead.getReturnMessage();
                    if(!"0000".equals(returnCode)){
                        resObj.put("code","300");
                        resObj.put("msg",returnMessage);
                        return resObj;
                    }
                    String refundNo = resInfo.getRefundNo();//缴费中心-退款流水号
                    String amtRefund = info.getAmtRefund();//退款金额

                    //取消收费处理
                    Result<?> result = chgFeesService.cancelChargeByPay(chgPayments);
                    if(!result.isSuccess()){
                        resObj.put("code","300");
                        resObj.put("msg",result.getMessage());
                    }else{
                        resObj.put("code","200");
                        resObj.put("msg","取消成功");

                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                resObj.put("code","300");
                resObj.put("msg","返回签名解析失败");
            }
        }
        return resObj;
    }

    /**
     * 下载对账单-今天下载昨日记录
     *
     */
    @Override
    public void abcBillFileDown() {
        //输入项避免首尾出现空格的情况
        ThirdAppTypeItemVo payAbcItem = thirdAppConfig.getPayAbc();
        String merchantId = payAbcItem.getClientId();
        String billDate = null;

        Calendar calendar = DateUtils.getCalendar();
        calendar.add(Calendar.DAY_OF_MONTH,-1);
        billDate = DateUtils.formatDate(calendar.getTime(),"yyyyMMdd");

        //创建发送请求对象
        DownloadTraceRequest req = new DownloadTraceRequest();
        //以系统当前时间为时间戳
        String timeStamp =DateUtils.formatDate("yyyyMMddHHmmssSSS");

        //封装数据格式为json格式 固定
        req.setFormat("json");
        // 关联交易的交易序列号需由第三方提供，且必须按照特定规则上送缴费中心，规则定义：BRIDGE前缀+当前17位时间戳timeStamp+商户号merchantId
        req.getMessage().getHead().setTransSeqNum("BRIDGE"+timeStamp+merchantId);
        //交易码，固定
        req.getMessage().getHead().setTransCode("downloadTrace");
        //上下行标志 固定
        req.getMessage().getHead().setTransFlag("01");
        //时间戳格式 yyyyMMddHHmmssSSS，
        req.getMessage().getHead().setTimeStamp(timeStamp);

        //对账单文件格式 固定值：CSV（大写）或GZ
        req.getMessage().getInfo().setFileType("CSV");
        //编码格式 固定值：UTF-8（大写）
        req.getMessage().getInfo().setCharset("UTF-8");
        //缴费中心商户编号，以商户为唯一维度来下载对账单
        req.getMessage().getInfo().setMerchantId(merchantId);
        //指定对账单的下载日期  跟下载的交易流水交易日期对应,格式yyyyMMdd
        req.getMessage().getInfo().setBillDate(billDate);

        //对账单类型billType有两个选项：
        //	ALL：暂不提供+
        //	SUCCESS：下载所有支付成功流水及所有退款成功流水，对应缴费状态为1、5、6、4，退款SUCCESS
        req.getMessage().getInfo().setBillType("SUCCESS");

        //将封装的请求对象转化为json格式
        String reqJson = JSON.toJSONString(req);
        //logger.info("加密前发送的请求报文：" + reqJson);
        //加签名
        String signatrue = signAndVerificationForAbc.signWhithsha1withrsa(thirdAppConfig.getPayAbc(),reqJson);
        //拼接发送的报文信息
        String reqStr = signatrue+"||"+Base64Util.encodeData(reqJson);
        //logger.info("发送的请求报文：" + reqStr);
        //发送请求并返回给前台,无返回值
        String outPath="D:/wwwroot/bill/abc"+ DateUtils.getDate("yyyyMMdd")+".CVS";
        JSONObject resObject = HttpClientUtils.doPostFile(CommonThirdConstant.ABC_BRIDGE_DOWNLOADTRACE, reqStr, outPath);
        //
        //if("200".equals(resObject.getString("code"))){
        //
        //}
    }
}
